package com.itheima.mybatis.framework;

import org.apache.ibatis.binding.BindingException;
import org.apache.ibatis.binding.MapperProxyFactory;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author ：sean
 * @date ：Created in 2020/7/5
 * @description ：
 * @version: 1.0
 */
public class HmMapperRegistry {
  private HmConfiguration configuration;

  private final Map<Class<?>, HmMapperProxyFactory<?>> knownMappers = new HashMap<>();

  public HmMapperRegistry(HmConfiguration configuration){
    this.configuration = configuration;
  }

  /**
   * 模拟实现
   * Mybatis真正的实现比这个更复杂，但最终是通过MapperRegistry获取的代理对象
   * @param type
   * @param sqlSession
   * @param <T>
   * @return
   */
  public <T> T getMapper(Class<T> type,HmSqlSession sqlSession) {
    final HmMapperProxyFactory<T> mapperProxyFactory
      = (HmMapperProxyFactory<T>) knownMappers.get(type);
    try {
      return mapperProxyFactory.newInstance(sqlSession);
    } catch (Exception e) {
      e.printStackTrace();
    }
    return null;
    /*
    Class clazz[] = new Class[]{type};
    Object  obj = Proxy.newProxyInstance(sqlSession.getClass().getClassLoader(), clazz,
      // 动态实现
      new InvocationHandler() {
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
          // 动态实现方法内容
          String pre = type.getName()+"."+method.getName();
          System.out.println(pre);
          if(pre.contains("toString")){
              return "toString:"+proxy.getClass().getName();
          }
          List<T> objects = sqlSession.selectList(pre);
          // 动态方法的返回值
          return objects;
        }
      });

    return (T)obj;
    */
  }

  public <T> void addMapper(Class<T> type) {
        knownMappers.put(type, new HmMapperProxyFactory<>(type));
    }

}

